package com.pm.framework.security.oaSso;

import com.alibaba.fastjson2.JSONObject;
import com.pm.common.config.ParamConfig;
import com.pm.framework.web.service.SsoUserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Collections;

@Component
public class OaAuthenticationProvider extends  AbstractUserDetailsAuthenticationProvider {

    @Autowired
    private SsoUserDetailsServiceImpl ssoUserDetailsService;


    @Resource
    ParamConfig paramConfig;

    @Resource
    RestTemplate restTemplate;

    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {

    }

    @Override
    protected UserDetails retrieveUser(String code, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
            String url = paramConfig.getOaAddr()+"/api/pro-sso/proSsoRestService/validate";
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf(MediaType.MULTIPART_FORM_DATA_VALUE));
            MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
            formData.put("tokenString", Collections.singletonList(code));
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(formData, headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
            JSONObject res = JSONObject.parseObject(responseEntity.getBody());
            logger.info("OA单点登录解析tokenString返回值:"+res.toJSONString());
        UserDetails userDetails = ssoUserDetailsService.loadUserByUserNo(res.getJSONObject("userInfo").getString("userNo"));
        if(userDetails == null){
            throw new InternalAuthenticationServiceException("OA单点登录异常:账号不存在");
        }
        return userDetails;
    }

    public boolean supports(Class<?> authentication) {
        return OaAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
